import functionnodes.FunctionNode;
import data.Value;

/**
 * @author loaner
 */
class functionnodes.FunctionNodeLambda extends FunctionNode {
	
	function FunctionNodeLambda() {
		super();
		funcname = "lambda";
		type = SPECIALFUNCTION;
	}
	
	public function reduceXMLtoValue( scope:Object, XMLargs:Array ):Value
	{
		var returnvalue:Value;
/*		
 * so: a lambda object
 * has its own scope, which is child to the scope in which it was created,
 * and a list of parameter names
 * and a body of XML.
	 * 
	 Here's a sample call:
	  * <list>
	  * 		<symbol>lambda</symbol>
	  * 		<list>
	  * 			<q>thenumber</q>
	  * 		</list>
	  * 		<list>
	  * 			<symbol>add</symbol>
	  * 			<symbol>thenumber</symbol>
	  * 			<symbol>10</symbol>
	  * 		</list>
	  * 	</list>
	  * 	
	  */
	  
	  	var fn:FunctionNode = new FunctionNode();
	  	
	  	//we're creating a new scope for the FunctionNode,
	  	//defined here at lexical scope,
	  	//whose only initial qualities will be:
	  	//1) it's a child of the scope we got here when the lambda function was called,
	  	//2) it defines the parameters that this function is supposed to receive.
	  	
	  	fn.lambdascope = { scopeparent:scope };
	  	
	  	fn.paramnames = new Array();
	  	
	  	var paramXML:XMLNode = XMLargs[0];
	  	
	  	for (var i:Number = 0; i < paramXML.childNodes.length; i++)
	  	{
	  		var paramname:String = Evaluator.convertXMLtoValue( paramXML.childNodes[i], scope).raw();
	  		fn.paramnames.push( paramname );
	  		trace("We pushed into paramnames " + paramname );	
	  	}
	  	
	  	fn.XMLcontent = XMLargs[ 1 ];
	  	
	  	trace("fn.paramnames = " + fn.paramnames);
	  	trace("fn.XMLcontent = " + fn.XMLcontent);
	  	
	  	fn.reduceValues = function( funcscope, funcargs ):Value
	  	{
	  		var funcreturnvalue:Value;
	  		
	  		trace("this.paramnames = " + this.paramnames);
	  		for( var i:Number = 0; i < this.paramnames.length; i++)
	  		{
	  			this.lambdascope[ this.paramnames[ i ] ] = funcargs[ i ];
	  		}
	  		
	  		funcreturnvalue = Evaluator.convertXMLtoValue( this.XMLcontent, this.lambdascope );
	  		
	  		return funcreturnvalue;
	  	};
		
		returnvalue = new Value( Value.FUNCTIONNODE, fn);	
		return returnvalue;
	}

}